package com.chinalcoal.ai.utils.util;

import com.itextpdf.text.pdf.PdfReader;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class PDFPasswordCracker {
    private final String pdfFilePath;
    private String foundPassword = null;
    private boolean isCracked = false;
    
    public PDFPasswordCracker(String pdfFilePath) {
        this.pdfFilePath = pdfFilePath;
    }

    public static void main(String[] args) {
        // PDF文件路径
        String pdfPath = "G:\\我的项目\\PDF转图片\\三色笔记.pdf";

        PDFPasswordCracker cracker = new PDFPasswordCracker(pdfPath);

        // 方法1: 暴力破解 - 尝试简单密码
        String charset = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        String password = cracker.bruteForceCrack(1, 6, charset);

        // 方法2: 字典破解 - 准备常用密码字典
        /*
        List<String> dictionary = new ArrayList<>();
        dictionary.add("123456");
        dictionary.add("password");
        dictionary.add("12345678");
        dictionary.add("qwerty");
        // 可以从文件中读取更多密码
        String password = cracker.dictionaryCrack(dictionary);
        */

        if (password != null) {
            System.out.println("成功破解，密码是: " + password);
        } else {
            System.out.println("破解失败，未找到密码");
        }
    }
    
    // 检查密码是否正确
    private boolean checkPassword(String password) {
        try {
            PdfReader reader = new PdfReader(pdfFilePath, password.getBytes());
            reader.close();
            return true;
        } catch (IOException e) {
            return false;
        }
    }
    
    // 暴力破解 - 尝试指定长度和字符集的所有可能密码
    public String bruteForceCrack(int minLength, int maxLength, String charset) {
        if (!new File(pdfFilePath).exists()) {
            System.err.println("PDF文件不存在！");
            return null;
        }
        
        System.out.println("开始暴力破解...");
        long startTime = System.currentTimeMillis();
        
        // 多线程破解提高效率
        ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
        
        for (int length = minLength; length <= maxLength; length++) {
            if (isCracked) break;
            
            System.out.println("尝试长度为 " + length + " 的密码...");
            char[] current = new char[length];
            bruteForceRecursive(current, 0, charset, executor);
        }
        
        executor.shutdown();
        try {
            executor.awaitTermination(24, TimeUnit.HOURS); // 等待所有线程完成
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        
        long endTime = System.currentTimeMillis();
        System.out.println("破解结束，耗时: " + (endTime - startTime) / 1000 + "秒");
        
        return foundPassword;
    }
    
    // 递归生成密码并尝试
    private void bruteForceRecursive(char[] current, int position, String charset, ExecutorService executor) {
        if (isCracked) return;
        
        if (position == current.length) {
            executor.execute(() -> {
                if (!isCracked) {
                    String password = new String(current);
                    if (checkPassword(password)) {
                        foundPassword = password;
                        isCracked = true;
                        System.out.println("找到密码: " + password);
                    }
                }
            });
            return;
        }
        
        for (char c : charset.toCharArray()) {
            if (isCracked) return;
            current[position] = c;
            bruteForceRecursive(current, position + 1, charset, executor);
        }
    }
    
    // 字典破解 - 从字典文件中读取密码尝试
    public String dictionaryCrack(List<String> dictionary) {
        if (!new File(pdfFilePath).exists()) {
            System.err.println("PDF文件不存在！");
            return null;
        }
        
        System.out.println("开始字典破解，共 " + dictionary.size() + " 个密码...");
        long startTime = System.currentTimeMillis();
        
        for (String password : dictionary) {
            if (checkPassword(password)) {
                long endTime = System.currentTimeMillis();
                System.out.println("找到密码: " + password + "，耗时: " + (endTime - startTime) / 1000 + "秒");
                return password;
            }
        }
        
        long endTime = System.currentTimeMillis();
        System.out.println("字典中未找到正确密码，耗时: " + (endTime - startTime) / 1000 + "秒");
        return null;
    }
    

}
